
package com.dream.utils.image;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import net.coobird.thumbnailator.Thumbnails;

import com.dream.utils.io.FileIOUtils;
import com.dream.utils.log.DreamLogUtils;
import com.dream.utils.system.cfg.SystemConfigUtils;
import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.MetadataException;
import com.drew.metadata.exif.ExifSubIFDDirectory;

/**
 * 
 * @copyright evan
 * @author evan
 * @date 2013-9-2
 */
public class ImageUtils {
	
	private static int IMAGE_MAX_SIZE = 1920;
	static {
		IMAGE_MAX_SIZE = SystemConfigUtils.instance().getInteger("system.image.maxsize", 1920);
	}
	/**
	 * get exif picture info
	 * @param in
	 * @return
	 * @throws Exception
	 */
	public static PictureExifInfo getExifInfo(InputStream in) {
		
		PictureExifInfo exif = new PictureExifInfo();
		exif.init();
		
		Metadata metadata = null;
		try {
			metadata = JpegMetadataReader.readMetadata(in);
			Directory dir = metadata.getDirectory(ExifSubIFDDirectory.class);
			if( null != dir){
				if (dir.containsTag(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL)) {
					exif.setCreateTime(dir.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL));
				} 
				if (dir.containsTag(ExifSubIFDDirectory.TAG_DOCUMENT_NAME)) {
					exif.setName(dir.getString(ExifSubIFDDirectory.TAG_DOCUMENT_NAME));
				} 
				
				if (dir.containsTag(ExifSubIFDDirectory.TAG_EXIF_IMAGE_HEIGHT)) {
					exif.setHeight(dir.getInt(ExifSubIFDDirectory.TAG_EXIF_IMAGE_HEIGHT));
				} 
				
				if (dir.containsTag(ExifSubIFDDirectory.TAG_EXIF_IMAGE_WIDTH)) {
					exif.setHeight(dir.getInt(ExifSubIFDDirectory.TAG_EXIF_IMAGE_WIDTH));
				} 
			}
			
		} catch (JpegProcessingException e) {
			DreamLogUtils.error(ImageUtils.class,"getExifInfo","",e);
			throw new RuntimeException(e);
		}catch (MetadataException e) {
			DreamLogUtils.error(ImageUtils.class,"getExifInfo","",e);
			throw new RuntimeException(e);
		}
		return exif;
	}
	
	/**
	 * convert image type
	 * @param in
	 * @param file
	 * @param desc
	 */
	public static void convertImgType(File in ,File out,ImageType desc){
		
		try {
			if(validateImageSize(in)){
				PictureExifInfo exif = getExifInfo(new FileInputStream(in));
				Thumbnails.of(in).size(exif.getWidth(), exif.getHeight()).toFile(out);
			}
		} catch (IOException e) {
			DreamLogUtils.error(ImageUtils.class,"convertImgType","",e);
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * resize image by size
	 * @param in
	 * @param out
	 * @param width
	 * @param height
	 */
	public static void resizeImage(File in ,File out,int width,int height){
		
		try {
			if(validateImageSize(in)){
				Thumbnails.of(in).size(width, height).toFile(out);
			}
		} catch (IOException e) {
			DreamLogUtils.error(ImageUtils.class,"resizeImage","",e);
			throw new RuntimeException(e);
		}
		
	}
	
	/**
	 * resize image by scale
	 * @param in
	 * @param out
	 * @param ratio
	 */
	public static void scaleImage(File in ,File out,float ratio){
		try {
			if(validateImageSize(in)){
				Thumbnails.of(in).scale(ratio).toFile(out);
			}
		} catch (IOException e) {
			DreamLogUtils.error(ImageUtils.class,"scaleImage","",e);
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * thumbnail the image default : 140*140
	 * @param in
	 * @param file
	 */
	public static void thumbnailImage(File in ,File file){
		if(validateImageSize(in)){
			int width = SystemConfigUtils.instance().getInteger("system.image.width", 140);
			int height = SystemConfigUtils.instance().getInteger("system.image.height", 140);
			resizeImage(in,file,width,height);
		}
	}

	/**
	 * get new file object
	 * @param path
	 * @param fileName
	 * @param fileSuffix
	 * @return
	 */
	public static File getNewFile(ImagePathType path , String fileName , ImageType type) {

		String fullPath = new StringBuilder(path.getImagePath()).append(fileName).append(type.getImageSuffix()).toString();
		File file = new File(fullPath);
	    FileIOUtils.forceMakeDir(file);
	    return file;
	}
	
	public static boolean validateImageSize(File in){
		if(in.length() > IMAGE_MAX_SIZE){
			return false;
		}
		return true;
	}
}
